﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using MH.CRM.Summary.CrmSdk;
using System.Windows.Browser;
using System.Collections.ObjectModel;
using System.Windows.Media.Imaging;

namespace MH.CRM.Summary
{
    public partial class MainPage : UserControl
    {
        private const int pageSize = 100;
        private int page = 1;
        ObservableCollection<EntityMetadata> entitiesMetadata;
        IDictionary<string, string> initParams;
        private HyperlinkButton hyperlinkLoadMore = new HyperlinkButton();

        public static DateTime BestDate(Entity activity)
        {
            if (activity.Attributes.ContainsKey("actualend"))
            {
                return activity.GetAttributeValue<DateTime>("actualend");
            }
            else if (activity.Attributes.ContainsKey("scheduledend"))
            {
                return activity.GetAttributeValue<DateTime>("scheduledend");
            }
            else
            {
                return activity.GetAttributeValue<DateTime>("createdon");
            }
        }

        public MainPage(App app, IDictionary<string,string> initParams)
        {
            InitializeComponent();
            this.initParams = initParams;            
            app.UnhandledException += new EventHandler<ApplicationUnhandledExceptionEventArgs>(app_UnhandledException);
            hyperlinkLoadMore.Content = "Load more...";
            hyperlinkLoadMore.Click += new RoutedEventHandler(hyperlinkLoadMore_Click);

            Loaded += new RoutedEventHandler(MainPage_Loaded);            
        }

        void hyperlinkLoadMore_Click(object sender, RoutedEventArgs e)
        {
            this.page++;
            this.listBoxActivities.Items.Remove(hyperlinkLoadMore);
            ActivityRollupReqest();
        }

        private void ReportError(Exception ex)
        {
            this.ReportMessage("Exception: " + SilverlightUtility.ConvertToString(ex));
        }

        private void ReportMessage(string message)
        {
            this.Dispatcher.BeginInvoke(() => 
                {
                    MessageBox.Show(message);
                    this.BusyIndicator.IsBusy = false;
                });
        }

        private void app_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            this.ReportError(e.ExceptionObject);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {

            if (!initParams.ContainsKey("id") || String.IsNullOrEmpty(initParams["id"]))
            {
                this.HyperlinkButtonRefresh.IsEnabled = false;
                BusyIndicator.IsBusy = false;
                return;
            }

            RetrieveAllEntitiesReqest();
        }

        private void ActivityRollupReqest()
        {
            BusyIndicator.IsBusy = true;

            IOrganizationService service = SilverlightUtility.GetSoapService();
            //Get object type and id
            Guid objectid = new Guid(initParams["id"]);            
            string typename = initParams["typename"];            

            OrganizationRequest rollupReqest = new OrganizationRequest() { RequestName = "Rollup" };
            if (typename.ToLower() == "account" || typename.ToLower() == "contact")
            {
                rollupReqest["RollupType"] = RollupType.Related;
            }
            else
            {
                rollupReqest["RollupType"] = RollupType.None;
            }
            rollupReqest["Target"] = new EntityReference()
            {
                Id = objectid,
                LogicalName = typename
            };
            rollupReqest["Query"] = new QueryExpression()
            {
                ColumnSet = new ColumnSet()
                {
                    AllColumns = true
                },
                EntityName = "activitypointer",
                Orders = new ObservableCollection<OrderExpression>()
                {
                    new OrderExpression()
                    {
                        AttributeName = "modifiedon",
                        OrderType = OrderType.Descending
                    }
                },
                PageInfo = new PagingInfo()
                {
                    PageNumber = page,
                    Count = pageSize
                }
            };

            service.BeginExecute(rollupReqest, new AsyncCallback(ActivityRollup_Callback), service);
        }

        private void RetrieveAllEntitiesReqest()
        {
            IOrganizationService service = SilverlightUtility.GetSoapService();
            OrganizationRequest retriveAllEntitiesReqest = new OrganizationRequest() { RequestName = "RetrieveAllEntities" };
            retriveAllEntitiesReqest["EntityFilters"] = EntityFilters.Entity;
            retriveAllEntitiesReqest["RetrieveAsIfPublished"] = false;

            service.BeginExecute(retriveAllEntitiesReqest, new AsyncCallback(RetriveAllEntities_Callback), service);
        }

        private void ActivityRollup_Callback(IAsyncResult result)
        {            
            OrganizationResponse response = ((IOrganizationService)result.AsyncState).EndExecute(result);
            EntityCollection results = (EntityCollection)response["EntityCollection"];
            this.listBoxActivities.Dispatcher.BeginInvoke(() =>
            {
                BusyIndicator.IsBusy = false;
                foreach (Entity entity in from el in results.Entities orderby  BestDate(el) descending select el)
                {
                    EntityMetadata activityMetadata = (from el in entitiesMetadata where el.LogicalName == entity.GetAttributeValue<string>("activitytypecode") select el).First();
                    ActivityRow activityRow = new ActivityRow();
                    listBoxActivities.Items.Add(activityRow);
                    activityRow.Init(entity, activityMetadata);                    
                }

                if (results.MoreRecords)
                {
                    listBoxActivities.Items.Add(hyperlinkLoadMore);
                }
            });
        }
        
        private void RetriveAllEntities_Callback(IAsyncResult result)
        {
            OrganizationResponse response;

            try
            {
                response = ((IOrganizationService)result.AsyncState).EndExecute(result);
                entitiesMetadata = (ObservableCollection<EntityMetadata>)response["EntityMetadata"];
            }
            catch
            {
                this.listBoxActivities.Dispatcher.BeginInvoke(() =>
                {
                    MessageBox.Show("Activity Summary extension cannot connect to crm server. Make sure you connect to CRM with following url: " + SilverlightUtility.GetServerBaseUrl());
                });
                return;
            }

            this.listBoxActivities.Dispatcher.BeginInvoke(() =>
            {
                //Add "Add New acitivity" buttons
                foreach (EntityMetadata entityMetadata in from el in entitiesMetadata 
                                                          where el.IsActivity == true
                                                          && (el.IsCustomEntity == true || el.ObjectTypeCode == 4212 || el.ObjectTypeCode == 4202
                                                          || el.ObjectTypeCode == 4210 || el.ObjectTypeCode == 4204 || el.ObjectTypeCode == 4207
                                                          || el.ObjectTypeCode == 4201 || el.ObjectTypeCode == 4214) orderby el.ObjectTypeCode
                                                          select el)
                {
                    
                    Image imageNewActivity = new Image();
                    imageNewActivity.Tag = entityMetadata;
                    imageNewActivity.Stretch = Stretch.None;
                    if (entityMetadata.IsCustomEntity == false)
                    {
                        imageNewActivity.Source = new BitmapImage(new Uri("/MH.CRM.Summary;component/imgs/ico_16_" + entityMetadata.ObjectTypeCode + ".png", UriKind.Relative)); ;
                    }
                    else if (entityMetadata.IconSmallName == null)
                    {
                        imageNewActivity.Source = new BitmapImage(new Uri("/MH.CRM.Summary;component/imgs/ico_16_CustomActivity.png", UriKind.Relative));
                    }
                    else
                    {
                        imageNewActivity.Source = new BitmapImage(new Uri(SilverlightUtility.GetServerBaseUrl() + "/WebResources/" + entityMetadata.IconSmallName,UriKind.Absolute));
                    }

                    imageNewActivity.Margin = new Thickness(2);

                    HyperlinkButton buttonNewActivity = new HyperlinkButton();
                    buttonNewActivity.Tag = entityMetadata;
                    buttonNewActivity.Content = imageNewActivity;
                    buttonNewActivity.Margin = new Thickness(10, 2, 2, 2);
                    buttonNewActivity.Width = 20;
                    buttonNewActivity.Click += new RoutedEventHandler(buttonNewActivity_Click);

                    Style style = Application.Current.Resources["ImageButton"] as Style;
                    buttonNewActivity.Style = style;

                    this.PanelButtons.Children.Add(buttonNewActivity);
                }

                string typename = initParams["typename"];
                if (typename.ToLower() == "account" || typename.ToLower() == "contact")
                {
                    ActivityRollupReqest();
                }
                else
                {
                    ActivityQueryRequest();
                }
            });

            
        }

        private void ActivityQueryRequest()
        {
            BusyIndicator.IsBusy = true;

            IOrganizationService service = SilverlightUtility.GetSoapService();
            //Get object type and id
            Guid objectid = new Guid(initParams["id"]);
            string typename = initParams["typename"];

            OrganizationRequest retrieveMultipleReqest = new OrganizationRequest() { RequestName = "RetrieveMultiple" };
            QueryExpression query = new QueryExpression()
            {
                EntityName = "activitypointer",
                ColumnSet = new ColumnSet()
                {
                    AllColumns = true
                },
                Criteria = new FilterExpression()
                {
                    Conditions = new System.Collections.ObjectModel.ObservableCollection<ConditionExpression>() 
                    { 
                        new ConditionExpression() { AttributeName = "regardingobjectid", Operator = ConditionOperator.Equal , Values = new System.Collections.ObjectModel.ObservableCollection<object>() { objectid } },                            
                    }
                },
                Orders = new ObservableCollection<OrderExpression>()
                {
                    new OrderExpression()
                    {
                        AttributeName = "modifiedon",
                        OrderType = OrderType.Descending
                    }
                },
                PageInfo = new PagingInfo()
                {
                    PageNumber = page,
                    Count = pageSize
                }
            };
            retrieveMultipleReqest["Query"] = query;
            service.BeginExecute(retrieveMultipleReqest, new AsyncCallback(RetrieveActivities_Callback), service);
        }

        private void RetrieveActivities_Callback(IAsyncResult result)
        {
            OrganizationResponse response = ((IOrganizationService)result.AsyncState).EndExecute(result);
            EntityCollection results = (EntityCollection)response["EntityCollection"];

            this.listBoxActivities.Dispatcher.BeginInvoke(() =>
            {
                BusyIndicator.IsBusy = false;
                foreach (Entity entity in from el in results.Entities orderby BestDate(el) descending select el)
                {
                    EntityMetadata activityMetadata = (from el in entitiesMetadata where el.LogicalName == entity.GetAttributeValue<string>("activitytypecode") select el).First();
                    ActivityRow activityRow = new ActivityRow();
                    activityRow.Init(entity, activityMetadata);                    
                    listBoxActivities.Items.Add(activityRow);                    
                }

                if (results.MoreRecords)
                {                    
                        listBoxActivities.Items.Add(hyperlinkLoadMore);
                }                
            });
        }

        void buttonNewActivity_Click(object sender, RoutedEventArgs e)
        {
            EntityMetadata activityMetadata = (sender as HyperlinkButton).Tag as EntityMetadata;
            string link = SilverlightUtility.GetServerBaseUrl().ToString().TrimEnd().TrimEnd(new char[] {'/'});
            string typename = initParams["typename"];
            if (typename.ToLower() == "account" || typename.ToLower() == "contact")
            {
                link += string.Format("/main.aspx?etc={0}&extraqs=%3fcontactInfo%3d%26etc%3d{0}%26pId%3d{1}%26pType%3d{2}%26pagemode%3diframe%26partyid%3d{1}%26partytype%3d{2}&pagetype=entityrecord",
                    activityMetadata.ObjectTypeCode, initParams["id"].Replace("{", "%257b").Replace("}", "%257d"), initParams["type"]);
            }
            else
            {
                link += string.Format("/main.aspx?etc={0}&extraqs=%3fcontactInfo%3d%26etc%3d{0}%26pId%3d{1}%26pType%3d{2}%26pagemode%3diframe&pagetype=entityrecord",
                    activityMetadata.ObjectTypeCode, initParams["id"].Replace("{", "%257b").Replace("}", "%257d"), initParams["type"]);
            }
            HtmlPage.Window.Navigate(new Uri(link), "_blank", "directories=no,fullscreen=no,menubar=no,resizable=yes,scrollbars=yes,status=no,titlebar=yes,toolbar=no");
        }
      
        private void listBoxActivities_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (listBoxActivities.SelectedItem != null)
            {
                ActivityRow activityRow = listBoxActivities.SelectedItem as ActivityRow;

                this.TextBlockSubject.Text = activityRow.Subject;
                this.TextBlockDate.Text = activityRow.Date;
                this.TextBlockDescription.Text = activityRow.Description;
                this.TextBlockFrom.Text = activityRow.From;
                this.TextBlockTo.Text = activityRow.To;

                this.ScrollViewerDescription.ScrollToVerticalOffset(0);
            }
        }


        private void HyperlinkButtonRefresh_Click(object sender, RoutedEventArgs e)
        {
            page = 1;
            this.listBoxActivities.Items.Clear();
            this.TextBlockDate.Text = "";
            this.TextBlockDescription.Text = "";
            this.TextBlockFrom.Text = "";
            this.TextBlockSubject.Text = "";
            this.TextBlockTo.Text = "";
            string typename = initParams["typename"];

            if (typename.ToLower() == "account" || typename.ToLower() == "contact")
            {
                ActivityRollupReqest();
            }
            else
            {
                ActivityQueryRequest();
            }
        }

        

    }
}
